import { GameModel } from "./GameModel";
import { EventKey } from "../common/Key";
import { CellHeight, TestLevel } from "./GameDefine";
import { GameData } from "./GameData";

const GameState = {
    gaming: 0,
    over: 1,
}

cc.Class({
    extends: cc.Component,

    properties: {
        nodCellParent: cc.Node,
        nodEffectParent: cc.Node,
        nodEffectParent2: cc.Node,
        nodCore: cc.Node,
    },

    onLoad() {
        this._registeEvent();
    },
    onDestroy() {
        this._unRegisteEvent();
    },
    _unRegisteEvent() {
        G.onFire.off(EventKey.EVENT_CLICK_CELL, this._onFire, this);
    },
    startGame() {
        this._parseJsonData();
        this.gameModel = new GameModel();

        this._initCellViews();
        this._addCellViews();
        this._centerBoard();

        this.gameState = GameState.gaming;
    },

    startNextGame() {
        // 回收格子节点
        this._removeNodCells();
        this._resetBoardPos();
        // 开始游戏
        this._parseJsonData();
        this.gameModel = new GameModel();

        this._initCellViews();
        this._addCellViews();
        this._centerBoard();

        this.gameState = GameState.gaming;
    },

    _removeNodCells() {
        for (let y = 0; y < 9; y++) {
            for (let x = 0; x < 11; x++) {
                let cellView = this.cellViews[y][x];
                if (!cellView) {
                    continue;
                }
                this._removeItemKnot(cellView.node.getChildByName('core').getChildByName('knotParent'));
                G.utils.putPoolNode('nodePoolCell', cellView.node);
            }
        }
    },

    _removeItemKnot(parent) {
        for (let i = 0; i < parent.children.length; i++) {
            G.utils.putPoolNode('nodePoolKnot', parent.children[i]);
            i--;
        }
    },

    _registeEvent() {
        G.onFire.on(EventKey.EVENT_CLICK_CELL, this._onFire, this);

    },

    _onFire(eventName, param) {
        if (eventName == EventKey.EVENT_CLICK_CELL) {
            this._clickCell(param);
        }
    },

    _getOneValidCell() {
        for (let y = 0; y < 9; y++) {
            for (let x = 0; x < 11; x++) {
                let cellView = this.cellViews[y][x];
                if (cellView) {
                    return cellView
                }
            }
        }
    },

    _resetBoardPos() {
        this.nodCellParent.x = 0;
        this.nodCellParent.y = 0;

        this.nodEffectParent.x = 0;
        this.nodEffectParent.y = 0;
    },

    _centerBoard() {
        let minX = 0;
        let minY = 0;
        let maxX = 0;
        let maxY = 0;
        let cellView = this._getOneValidCell();
        let node = cellView.node;
        minX = node.x;
        maxX = node.x
        minY = node.y;
        maxY = node.y;

        for (let y = 0; y < 9; y++) {
            for (let x = 0; x < 11; x++) {
                let cellView = this.cellViews[y][x];
                if (!cellView) {
                    continue;
                }

                let node = cellView.node;
                if (node.x < minX) {
                    minX = node.x;
                }
                if (node.x > maxX) {
                    maxX = node.x
                }
                if (node.y < minY) {
                    minY = node.y;
                }
                if (node.y > maxY) {
                    maxY = node.y;
                }
            }
        }

        let offsetX = (maxX + minX) / 2;
        let offsetY = (maxY + minY) / 2;

        this.nodCellParent.x -= offsetX;
        this.nodCellParent.y -= offsetY;

        this.nodEffectParent.x -= offsetX;
        this.nodEffectParent.y -= offsetY;
        this.nodCore.scale = 2

        let boardWidth = maxX - minX + CellHeight;
        if (boardWidth * this.nodCore.scale > 720) {
            let scale = 720 / (boardWidth);
            this.nodCore.scale = scale * 0.9;
        }
        cc.view.getCanvasSize().width;
    },

    _parseJsonData() {
        let datas = G.json.getJson(GameData.level + '');
        for (let i = 0; i < datas.length; i++) {
            let item = datas[i];
            let pos = item.pos;
            let posArr = pos.split('|');
            item.pos = { x: posArr[0], y: posArr[1] };
            let knotData = item.knotData;
            item.knotData = knotData.split('|');
            let succPos = item.succPos;
            posArr = succPos.split('|');
            item.succPos = { x: posArr[0], y: posArr[1] };;
        }
    },

    _initCellViews() {
        this.cellViews = [];
        for (let y = 0; y < 9; y++) {
            this.cellViews[y] = [];
        }
    },
    _addCellViews() {
        let cellModels = this.gameModel.getCellModels();
        for (let y = 0; y < 9; y++) {
            for (let x = 0; x < 11; x++) {
                let cellModel = cellModels[y][x];
                if (!cellModel) {
                    continue;
                }

                let node = G.utils.getPoolNode('nodePoolCell');
                node.parent = this.nodCellParent;
                let cellView = node.getComponent('CellView');
                cellView.init(cellModel);
                this.cellViews[y][x] = cellView;
            }
        }
    },

    _clickCell(pos) {
        if (this.gameState == GameState.over) {
            return;
        }
        let result = this.gameModel.clickCell(pos);
        let cellView = this.cellViews[pos.y][pos.x];
        if (result.code == 0) {

        } else if (result.code == 1) {
            cellView.select();
            this._playSelectEffect(pos);
        } else if (result.code == 2) {
            cellView.cancelSelect();
        } else if (result.code == 3) {
            let firstPos = result.firstPos;
            let firstCellView = this.cellViews[firstPos.y][firstPos.x];
            firstCellView.cancelSelect();
            // 交换
            // 交换this.cellViews中的位置
            this.cellViews[pos.y][pos.x] = firstCellView;
            this.cellViews[firstPos.y][firstPos.x] = cellView;
            // 移动
            cellView.moveTo(firstPos);
            firstCellView.moveTo(pos);

            this._checkGameOver();
        }
    },

    _getFixedCellView() {
        let cellModels = this.gameModel.getCellModels();
        for (let y = 0; y < 9; y++) {
            for (let x = 0; x < 11; x++) {
                let cellModel = cellModels[y][x];
                if (!cellModel) {
                    continue;
                }

                if (cellModel.getIsFixed() != 1) {
                    continue;
                }

                let pos = cellModel.getPos();
                return this.cellViews[pos.y][pos.x];
            }
        }
        return false;
    },

    _checkGameOver() {
        let isOver = this.gameModel.checkGameOver();
        if (!isOver) {
            return;
        }
        this.gameState = GameState.over;

        this.scheduleOnce(() => {
            let cellView = this._getFixedCellView();
            if (cellView) {
                cellView.cancelFixed();
            }
            this._playOverEffect();
            G.onFire.fire(EventKey.EVENT_GAME_OVER);
        }, 0.5)
        // G.game.toast('结束了',0.5);
    },

    _playSelectEffect(pos) {
        let node = G.utils.getPoolNode('nodePoolSelectEffect');
        node.parent = this.nodEffectParent;
        let pixX = pos.x * CellHeight * Math.cos(30 * Math.PI / 180) - 5 * CellHeight * Math.cos(30 * Math.PI / 180);
        let offsetY = pos.x % 2 == 0 ? CellHeight / 2 : 0;
        let pixY = offsetY + pos.y * CellHeight - 4 * CellHeight;
        node.position = cc.v2(pixX, pixY);
        node.getComponent(cc.Animation).play('animSelect');
        this.scheduleOnce(() => {
            G.utils.putPoolNode('nodePoolSelectEffect', node);
        }, 1)
    },

    _playOverEffect() {
        G.partner.vibrateLong();
        let node = G.utils.getPoolNode('nodePoolSelectEffect');
        node.parent = this.nodEffectParent2;
        node.position = cc.v2(0, 0);
        node.getComponent(cc.Animation).play('animOver');
        this.scheduleOnce(() => {
            G.utils.putPoolNode('nodePoolSelectEffect', node);
        }, 1)
    },

    turnBegin() {
        if (this.gameState == GameState.over) {
            this.gameState = GameState.gaming;
            GameData.subLevel();
        }
    },

    turnSucc() {
        GameData.succMode = true;
        this._removeNodCells();
        this.gameModel = new GameModel();

        this._initCellViews();
        this._addCellViews();
        GameData.succMode = false;
    },

    checkOver() {
        this._checkGameOver();
    },
    // update (dt) {},
});
